<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Ollama 智能助手</title>
        <link rel="stylesheet" href="css/style.css" />
        <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
        <style></style>
    </head>
    <body>
        <div class="sidebar" id="sidebar">
            <div class="user-info sidebar-n"></div>
            <div class="menu-list sidebar-n">
                <div class="menu-item sidebar-n">
                    <img src="./img/new-message.png" /><span>新会话</span>
                </div>
                <div class="menu-item sidebar-n">
                    <img src="./img/search.png" /><span>搜索</span>
                </div>
                <div class="menu-item sidebar-n" id="theme-switch">
                    <img src="./img/themes-light.png" id="theme-icon" /><span
                        >主题</span
                    >
                </div>
            </div>
            <div class="session-history sidebar-n"></div>
        </div>
        <div class="content" id="content">
            <div class="toggle-button" id="toggle-sidebar">
                <img src="./img/sidebar.png" alt="" />
            </div>
            <h2 id="title">Ollama</h2>
            <div class="chat-container" id="chat-container">
                <!-- 聊天记录将动态插入到这里 -->
            </div>
            <div class="input-container">
                <select id="model-select"></select>
                <textarea
                    id="input"
                    placeholder="输入你的问题..."
                    rows="1"
                ></textarea>
                <button id="submit-button">发送</button>
            </div>
        </div>

        <script>
            // 获取输入框、选择框和提交按钮
            const input = document.getElementById("input");
            const modelSelect = document.getElementById("model-select");
            const submitButton = document.getElementById("submit-button");
            const sidebar = document.getElementById("sidebar");
            const toggleSidebarButton =
                document.getElementById("toggle-sidebar");
            const content = document.getElementById("content");
            const themeSwitch = document.getElementById("theme-switch");
            const themeIcon = document.getElementById("theme-icon");

            let current_session_id = "";
            let current_theme = 0;

            // 存储对话历史
            let conversationHistory = [];

            // 菜单默认是收起状态
            sidebar.classList.toggle("collapsed");
            // 切换菜单栏的显示状态
            toggleSidebarButton.addEventListener("click", () => {
                sidebar.classList.toggle("collapsed");
            });

            // 主题切换功能
            themeSwitch.addEventListener("click", () => {
                // 切换整个页面的夜间模式
                document.body.classList.toggle("night-mode");
                // 切换内容区域的夜间模式
                content.classList.toggle("night-mode");

                sidebar.classList.toggle("night-mode");

                // 获取所有机器人消息元素
                const botMessages = document.querySelectorAll(".bot-message");
                // 获取所有用户消息元素
                const userMessages = document.querySelectorAll(".user-message");
                const sidebars = document.querySelectorAll(".sidebar-n");

                // 为每个机器人消息切换夜间模式样式
                botMessages.forEach((msg) =>
                    msg.classList.toggle("night-mode")
                );
                // 为每个用户消息切换夜间模式样式
                userMessages.forEach((msg) =>
                    msg.classList.toggle("night-mode")
                );
                sidebars.forEach((msg) => msg.classList.toggle("night-mode"));

                // 切换图标
                if (document.body.classList.contains("night-mode")) {
                    themeIcon.src = "./img/themes-night.png"; // 夜间模式图标
                } else {
                    themeIcon.src = "./img/themes-light.png"; // 明亮模式图标
                }

                if (current_theme == 0) {
                    current_theme = 1;
                } else {
                    current_theme = 0;
                }

                console.log("-----------当前主题：" + current_theme);
            });

            // 为输入框添加键盘事件
            input.addEventListener("keydown", (e) => {
                if (e.key === "Enter" && !e.ctrlKey) {
                    e.preventDefault(); // 阻止默认换行行为
                    submitButton.click(); // 触发提交按钮点击事件
                } else if (e.key === "Enter" && e.ctrlKey) {
                    // 按 Ctrl + Enter 时换行
                    const start = input.selectionStart;
                    const end = input.selectionEnd;
                    input.value =
                        input.value.substring(0, start) +
                        "\n" +
                        input.value.substring(end);
                    input.selectionStart = input.selectionEnd = start + 1;
                }
            });

            // 获取当前时间，格式为 yyyy-mm-dd hh:mm:ss
            function getCurrentTime() {
                const now = new Date();
                const year = now.getFullYear();
                const month = String(now.getMonth() + 1).padStart(2, "0");
                const day = String(now.getDate()).padStart(2, "0");
                const hours = String(now.getHours()).padStart(2, "0");
                const minutes = String(now.getMinutes()).padStart(2, "0");
                const seconds = String(now.getSeconds()).padStart(2, "0");
                return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
            }

            // 提交按钮点击事件
            submitButton.addEventListener("click", async () => {
                const inputValue = input.value.trim();
                if (!inputValue) return; // 如果输入为空，则不处理

                const chatContainer = document.getElementById("chat-container");

                // 添加用户消息
                const userMessage = document.createElement("div");
                userMessage.className = "message user-message";
                userMessage.innerHTML = `
                ${inputValue}
                <div class="message-time">${getCurrentTime()}</div>
                `;
                chatContainer.appendChild(userMessage);

                // 清空输入框
                input.value = "";

                // 添加模型回复占位符
                const botMessage = document.createElement("div");
                if (current_theme === 1) {
                    botMessage.className = "message bot-message night-mode";
                } else {
                    botMessage.className = "message bot-message ";
                }

                botMessage.innerHTML = `
                处理中...
                <div class="message-time">${getCurrentTime()}</div>
                `;
                chatContainer.appendChild(botMessage);

                // 滚动到底部
                chatContainer.scrollTop = chatContainer.scrollHeight;

                try {
                    conversationHistory.push({
                        role: "user",
                        content: inputValue,
                    });
                    const response = await fetch(
                        "http://localhost:11434/api/chat",
                        {
                            method: "POST",
                            headers: {
                                "Content-Type": "application/json",
                            },
                            body: JSON.stringify({
                                model: modelSelect.value,
                                messages: conversationHistory,
                                stream: true, // 启用流式输出
                            }),
                        }
                    );

                    const reader = response.body.getReader();
                    const decoder = new TextDecoder();
                    let result = "";
                    while (true) {
                        const { done, value } = await reader.read();
                        if (done) break;

                        const chunk = decoder.decode(value);
                        const lines = chunk.split("\n");

                        for (const line of lines) {
                            if (line.trim() === "") continue;
                            const data = JSON.parse(line);
                            result += data.message.content;
                            botMessage.innerHTML = `
                                ${marked.parse(result)}
                                <div class="message-time">${getCurrentTime()}</div>
                            `;
                        }

                        // 滚动到底部
                        chatContainer.scrollTop = chatContainer.scrollHeight;
                    }

                    conversationHistory.push({
                        role: "assistant",
                        content: result,
                    });

                    // 会话ID为空，说明是新会话，则先保存会话信息
                    if (!current_session_id) {
                        // 生成18位随机字符串作为sessionId
                        current_session_id = Math.random()
                            .toString(36)
                            .substring(2, 20);

                        // 如果输入内容不为空，则截取前10个字符作为标题
                        title =
                            inputValue.trim() !== ""
                                ? inputValue.substring(0, 10)
                                : "新会话";

                        // 保存会话
                        add_session(current_session_id, title);
                        loadSessionHistory();
                    }
                    saveSessionMessages(current_session_id, [
                        {
                            session_id: current_session_id,
                            role: "user",
                            content: inputValue,
                        },
                        {
                            session_id: current_session_id,
                            role: "assistant",
                            content: result,
                        },
                    ]);
                } catch (error) {
                    console.error("Error:", error);
                    botMessage.innerHTML = `
                        调用 API 时出错: ${error.message}
                        <div class="message-time">${getCurrentTime()}</div>
                    `;
                }
            });

            async function loadModelOptions() {
                try {
                    const response = await fetch(
                        "http://localhost:11434/api/tags"
                    );
                    const data = await response.json();
                    const models = data.models;
                    const modelSelect = document.getElementById("model-select");

                    models.forEach((model) => {
                        const name = model.name;
                        const modelValue = model.model;
                        const sizeGB =
                            (model.size / 1024 ** 3).toFixed(1) + "G";
                        const option = document.createElement("option");
                        option.value = modelValue;
                        option.textContent = `${name} - ${sizeGB}`;
                        modelSelect.appendChild(option);
                    });
                } catch (error) {
                    console.error("Error loading model options:", error);
                }
            }

            // 加载会话列表
            async function loadSessionHistory() {
                try {
                    const response = await fetch(
                        "http://localhost:5000/api/history"
                    );
                    const data = await response.json();
                    const sessionHistory =
                        document.querySelector(".session-history");

                    // 清空现有会话列表
                    sessionHistory.innerHTML = "";

                    // 遍历返回的会话数据并生成div
                    data.forEach((session) => {
                        const sessionItem = document.createElement("div");
                        if (current_theme === 1) {
                            // 夜间场景
                            sessionItem.className = "session-item night-mode";
                        } else {
                            sessionItem.className = "session-item";
                        }

                        sessionItem.textContent = session.title || "新会话";
                        // 为会话项绑定点击事件
                        sessionItem.addEventListener("click", () => {
                            // 加载该会话的聊天记录
                            loadSessionChat(session.session_id, session.title);
                        });

                        // 创建图标容器
                        const iconContainer = document.createElement("div");
                        iconContainer.className = "icon-container";

                        // 添加编辑图标
                        const editIcon = document.createElement("img");
                        editIcon.src = "./img/edit.png";
                        editIcon.className = "icon";
                        editIcon.alt = "编辑";
                        editIcon.onclick = (event) => {
                            event.stopImmediatePropagation(); // 阻止事件继续传递
                            alert("编辑");
                            return false; // 可选，防止默认行为
                        };

                        // 添加删除图标
                        const deleteIcon = document.createElement("img");
                        deleteIcon.src = "./img/delete.png";
                        deleteIcon.className = "icon";
                        deleteIcon.alt = "删除";
                        deleteIcon.onclick = (event) => {
                            event.stopImmediatePropagation(); // 阻止事件继续传递
                            deleteSession(session.session_id);
                            return false; // 可选，防止默认行为
                        };

                        // 添加查看图标
                        const viewIcon = document.createElement("img");
                        viewIcon.src = "./img/view.png";
                        viewIcon.className = "icon";
                        viewIcon.alt = "查看";

                        // 将图标添加到容器
                        iconContainer.appendChild(editIcon);
                        iconContainer.appendChild(deleteIcon);
                        iconContainer.appendChild(viewIcon);

                        // 将图标容器添加到会话项
                        sessionItem.appendChild(iconContainer);

                        // 将会话项添加到会话历史
                        sessionHistory.appendChild(sessionItem);
                    });
                } catch (error) {
                    console.error("加载会话历史失败:", error);
                }
            }

            // 加载指定会话的聊天记录
            async function loadSessionChat(sessionId, title) {
                if (current_session_id == sessionId) {
                    console.log("--------------already load--------------");
                    return;
                }
                try {
                    // 发送GET请求获取指定会话的聊天记录
                    const response = await fetch(
                        `http://localhost:5000/api/messages/${sessionId}`
                    );
                    if (!response.ok) {
                        throw new Error(
                            `HTTP error! status: ${response.status}`
                        );
                    }
                    const data = await response.json();

                    // 清空当前聊天容器
                    const chatContainer =
                        document.getElementById("chat-container");
                    chatContainer.innerHTML = "";

                    // 遍历消息并添加到聊天容器
                    data.messages.forEach((message) => {
                        const messageDiv = document.createElement("div");
                        if (message.role == "user") {
                            if (current_theme === 1) {
                                messageDiv.className =
                                    "message user-message night-mode";
                            } else {
                                messageDiv.className = "message user-message";
                            }

                            messageDiv.innerHTML = `
                                ${message.content}
                                <div class="message-time">${message.create_time}</div>
                            `;
                        } else {
                            if (current_theme === 1) {
                                messageDiv.className =
                                    "message bot-message night-mode";
                            } else {
                                messageDiv.className = "message bot-message";
                            }
                            messageDiv.innerHTML = `
                                ${marked.parse(message.content)}
                                <div class="message-time">${
                                    message.create_time
                                }</div>
                            `;
                        }
                        chatContainer.appendChild(messageDiv);
                    });

                    current_session_id = sessionId;
                    changeTitle(title);

                    // 滚动到底部
                    chatContainer.scrollTop = chatContainer.scrollHeight;
                } catch (error) {
                    console.error("加载会话聊天记录失败:", error);
                }
            }

            // 添加保存会话消息列表的方法：请求地址：http://localhost:5000/api/save_messages, POST JSON
            // 保存会话消息列表
            async function saveSessionMessages(sessionId, messages) {
                try {
                    const response = await fetch(
                        "http://localhost:5000/api/save_messages",
                        {
                            method: "POST",
                            headers: {
                                "Content-Type": "application/json",
                            },
                            body: JSON.stringify({
                                session_id: sessionId,
                                messages: messages,
                            }),
                        }
                    );

                    if (!response.ok) {
                        throw new Error(`保存失败，状态码：${response.status}`);
                    }

                    const result = await response.json();
                    console.log("消息保存成功：", result);
                    return result;
                } catch (error) {
                    console.error("保存会话消息时出错：", error);
                    throw error;
                }
            }

            // 添加会话
            async function add_session(sessionId, title) {
                try {
                    const response = await fetch(
                        `http://localhost:5000/api/save_session?session_id=${sessionId}&title=${title}`,
                        {
                            method: "GET",
                        }
                    );

                    if (!response.ok) {
                        throw new Error(
                            `添加会话失败，状态码：${response.status}`
                        );
                    }

                    const result = await response.json();
                    console.log("会话添加成功：", result);
                    return result;
                } catch (error) {
                    console.error("添加会话时出错：", error);
                    throw error;
                }
            }

            // 根据session_id删除会话
            async function deleteSession(sessionId) {
                try {
                    const response = await fetch(
                        `http://localhost:5000/api/delete_session/${sessionId}`,
                        {
                            method: "DELETE",
                        }
                    );

                    if (!response.ok) {
                        throw new Error(
                            `删除会话失败，状态码：${response.status}`
                        );
                    }

                    const result = await response.json();
                    console.log("会话删除成功：", result);
                    // 这里可以添加代码来更新UI，例如重新加载会话列表
                    loadSessionHistory(); // 重新加载会话列表
                    return result;
                } catch (error) {
                    console.error("删除会话时出错：", error);
                    throw error;
                }
            }

            async function changeTitle(title) {
                const titleH1 = document.getElementById("title");
                titleH1.innerHTML = `${title}` || "Ollama";
            }

            // 在页面加载时调用
            window.addEventListener("load", loadSessionHistory);

            // 在页面加载时调用函数
            window.addEventListener("load", loadModelOptions);
        </script>
    </body>
</html>
